﻿/*
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
 *
 * == BEGIN LICENSE ==
 *
 * Licensed under the terms of any of the following licenses at your
 * choice:
 *
 *  - GNU General Public License Version 2 or later (the "GPL")
 *    http://www.gnu.org/licenses/gpl.html
 *
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 *    http://www.gnu.org/licenses/lgpl.html
 *
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 *
 * == END LICENSE ==
 *
 * Defines the FCKToolbarSet object that is used to load and draw the
 * toolbar.
 */

function FCKToolbarSet_Create( overhideLocation )
{
    var oToolbarSet ;

    var sLocation = overhideLocation || FCKConfig.ToolbarLocation ;
    switch ( sLocation )
    {
        case 'In' :
            document.getElementById( 'xToolbarRow' ).style.display = '' ;
            oToolbarSet = new FCKToolbarSet( document ) ;
            break ;
        case 'None' :
            oToolbarSet = new FCKToolbarSet( document ) ;
            break ;

//        case 'OutTop' :
            // Not supported.

        default :
            FCK.Events.AttachEvent( 'OnBlur', FCK_OnBlur ) ;
            FCK.Events.AttachEvent( 'OnFocus', FCK_OnFocus ) ;

            var eToolbarTarget ;

            // Out:[TargetWindow]([TargetId])
            var oOutMatch = sLocation.match( /^Out:(.+)\((\w+)\)$/ ) ;
            if ( oOutMatch )
            {
                if ( FCKBrowserInfo.IsAIR )
                    FCKAdobeAIR.ToolbarSet_GetOutElement( window, oOutMatch ) ;
                else
                    eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ;
            }
            else
            {
                // Out:[TargetId]
                oOutMatch = sLocation.match( /^Out:(\w+)$/ ) ;
                if ( oOutMatch )
                    eToolbarTarget = parent.document.getElementById( oOutMatch[1] ) ;
            }

            if ( !eToolbarTarget )
            {
                alert( 'Invalid value for "ToolbarLocation"' ) ;
                return arguments.callee( 'In' );
            }

            // If it is a shared toolbar, it may be already available in the target element.
            oToolbarSet = eToolbarTarget.__FCKToolbarSet ;
            if ( oToolbarSet )
                break ;

            // Create the IFRAME that will hold the toolbar inside the target element.
            var eToolbarIFrame = FCKTools.GetElementDocument( eToolbarTarget ).createElement( 'iframe' ) ;
            eToolbarIFrame.src = 'javascript:void(0)' ;
            eToolbarIFrame.frameBorder = 0 ;
            eToolbarIFrame.width = '100%' ;
            eToolbarIFrame.height = '10' ;
            eToolbarTarget.appendChild( eToolbarIFrame ) ;
            eToolbarIFrame.unselectable = 'on' ;

            // Write the basic HTML for the toolbar (copy from the editor main page).
            var eTargetDocument = eToolbarIFrame.contentWindow.document ;

            // Workaround for Safari 12256. Ticket #63
            var sBase = '' ;
            if ( FCKBrowserInfo.IsSafari )
                sBase = '<base href="' + window.document.location + '">' ;

            // Initialize the IFRAME document body.
            eTargetDocument.open() ;
            eTargetDocument.write( '<html><head>' + sBase + '<script type="text/javascript"> var adjust = function() { window.frameElement.height = document.body.scrollHeight ; }; '
                    + 'window.onresize = window.onload = '
                    + 'function(){'        // poll scrollHeight until it no longer changes for 1 sec.
                    + 'var timer = null;'
                    + 'var lastHeight = -1;'
                    + 'var lastChange = 0;'
                    + 'var poller = function(){'
                    + 'var currentHeight = document.body.scrollHeight || 0;'
                    + 'var currentTime = (new Date()).getTime();'
                    + 'if (currentHeight != lastHeight){'
                    + 'lastChange = currentTime;'
                    + 'adjust();'
                    + 'lastHeight = document.body.scrollHeight;'
                    + '}'
                    + 'if (lastChange < currentTime - 1000) clearInterval(timer);'
                    + '};'
                    + 'timer = setInterval(poller, 100);'
                    + '}'
                    + '</script></head><body style="overflow: hidden">' + document.getElementById( 'xToolbarSpace' ).innerHTML + '</body></html>' ) ;
            eTargetDocument.close() ;

            if( FCKBrowserInfo.IsAIR )
                FCKAdobeAIR.ToolbarSet_InitOutFrame( eTargetDocument ) ;

            FCKTools.AddEventListener( eTargetDocument, 'contextmenu', FCKTools.CancelEvent ) ;

            // Load external resources (must be done here, otherwise Firefox will not
            // have the document DOM ready to be used right away.
            FCKTools.AppendStyleSheet( eTargetDocument, FCKConfig.SkinEditorCSS ) ;

            oToolbarSet = eToolbarTarget.__FCKToolbarSet = new FCKToolbarSet( eTargetDocument ) ;
            oToolbarSet._IFrame = eToolbarIFrame ;

            if ( FCK.IECleanup )
                FCK.IECleanup.AddItem( eToolbarTarget, FCKToolbarSet_Target_Cleanup ) ;
    }

    oToolbarSet.CurrentInstance = FCK ;
    if ( !oToolbarSet.ToolbarItems )
        oToolbarSet.ToolbarItems = FCKToolbarItems ;

    FCK.AttachToOnSelectionChange( oToolbarSet.RefreshItemsState ) ;

    return oToolbarSet ;
}

function FCK_OnBlur( editorInstance )
{
    var eToolbarSet = editorInstance.ToolbarSet ;

    if ( eToolbarSet.CurrentInstance == editorInstance )
        eToolbarSet.Disable() ;
}

function FCK_OnFocus( editorInstance )
{
    var oToolbarset = editorInstance.ToolbarSet ;
    var oInstance = editorInstance || FCK ;

    // Unregister the toolbar window from the current instance.
    oToolbarset.CurrentInstance.FocusManager.RemoveWindow( oToolbarset._IFrame.contentWindow ) ;

    // Set the new current instance.
    oToolbarset.CurrentInstance = oInstance ;

    // Register the toolbar window in the current instance.
    oInstance.FocusManager.AddWindow( oToolbarset._IFrame.contentWindow, true ) ;

    oToolbarset.Enable() ;
}

function FCKToolbarSet_Cleanup()
{
    this._TargetElement = null ;
    this._IFrame = null ;
}

function FCKToolbarSet_Target_Cleanup()
{
    this.__FCKToolbarSet = null ;
}

var FCKToolbarSet = function( targetDocument )
{
    this._Document = targetDocument ;

    // Get the element that will hold the elements structure.
    this._TargetElement    = targetDocument.getElementById( 'xToolbar' ) ;

    // Setup the expand and collapse handlers.
    var eExpandHandle    = targetDocument.getElementById( 'xExpandHandle' ) ;
    var eCollapseHandle    = targetDocument.getElementById( 'xCollapseHandle' ) ;

    eExpandHandle.title        = FCKLang.ToolbarExpand ;
    FCKTools.AddEventListener( eExpandHandle, 'click', FCKToolbarSet_Expand_OnClick ) ;

    eCollapseHandle.title    = FCKLang.ToolbarCollapse ;
    FCKTools.AddEventListener( eCollapseHandle, 'click', FCKToolbarSet_Collapse_OnClick ) ;

    // Set the toolbar state at startup.
    if ( !FCKConfig.ToolbarCanCollapse || FCKConfig.ToolbarStartExpanded )
        this.Expand() ;
    else
        this.Collapse() ;

    // Enable/disable the collapse handler
    eCollapseHandle.style.display = FCKConfig.ToolbarCanCollapse ? '' : 'none' ;

    if ( FCKConfig.ToolbarCanCollapse )
        eCollapseHandle.style.display = '' ;
    else
        targetDocument.getElementById( 'xTBLeftBorder' ).style.display = '' ;

    // Set the default properties.
    this.Toolbars = new Array() ;
    this.IsLoaded = false ;

    if ( FCK.IECleanup )
        FCK.IECleanup.AddItem( this, FCKToolbarSet_Cleanup ) ;
}

function FCKToolbarSet_Expand_OnClick()
{
    FCK.ToolbarSet.Expand() ;
}

function FCKToolbarSet_Collapse_OnClick()
{
    FCK.ToolbarSet.Collapse() ;
}

FCKToolbarSet.prototype.Expand = function()
{
    this._ChangeVisibility( false ) ;
}

FCKToolbarSet.prototype.Collapse = function()
{
    this._ChangeVisibility( true ) ;
}

FCKToolbarSet.prototype._ChangeVisibility = function( collapse )
{
    this._Document.getElementById( 'xCollapsed' ).style.display = collapse ? '' : 'none' ;
    this._Document.getElementById( 'xExpanded' ).style.display = collapse ? 'none' : '' ;

    if ( FCKBrowserInfo.IsGecko )
    {
        // I had to use "setTimeout" because Gecko was not responding in a right
        // way when calling window.onresize() directly.
        FCKTools.RunFunction( window.onresize ) ;
    }
}

FCKToolbarSet.prototype.Load = function( toolbarSetName )
{
    this.Name = toolbarSetName ;

    this.Items = new Array() ;

    // Reset the array of toolbar items that are active only on WYSIWYG mode.
    this.ItemsWysiwygOnly = new Array() ;

    // Reset the array of toolbar items that are sensitive to the cursor position.
    this.ItemsContextSensitive = new Array() ;

    // Cleanup the target element.
    this._TargetElement.innerHTML = '' ;

    var ToolbarSet = FCKConfig.ToolbarSets[toolbarSetName] ;

    if ( !ToolbarSet )
    {
        alert( FCKLang.UnknownToolbarSet.replace( /%1/g, toolbarSetName ) ) ;
        return ;
    }

    this.Toolbars = new Array() ;

    for ( var x = 0 ; x < ToolbarSet.length ; x++ )
    {
        var oToolbarItems = ToolbarSet[x] ;

        // If the configuration for the toolbar is missing some element or has any extra comma
        // this item won't be valid, so skip it and keep on processing.
        if ( !oToolbarItems )
            continue ;

        var oToolbar ;

        if ( typeof( oToolbarItems ) == 'string' )
        {
            if ( oToolbarItems == '/' )
                oToolbar = new FCKToolbarBreak() ;
        }
        else
        {
            oToolbar = new FCKToolbar() ;

            for ( var j = 0 ; j < oToolbarItems.length ; j++ )
            {
                var sItem = oToolbarItems[j] ;

                if ( sItem == '-')
                    oToolbar.AddSeparator() ;
                else
                {
                    var oItem = FCKToolbarItems.GetItem( sItem ) ;
                    if ( oItem )
                    {
                        oToolbar.AddItem( oItem ) ;

                        this.Items.push( oItem ) ;

                        if ( !oItem.SourceView )
                            this.ItemsWysiwygOnly.push( oItem ) ;

                        if ( oItem.ContextSensitive )
                            this.ItemsContextSensitive.push( oItem ) ;
                    }
                }
            }

            // oToolbar.AddTerminator() ;
        }

        oToolbar.Create( this._TargetElement ) ;

        this.Toolbars[ this.Toolbars.length ] = oToolbar ;
    }

    FCKTools.DisableSelection( this._Document.getElementById( 'xCollapseHandle' ).parentNode ) ;

    if ( FCK.Status != FCK_STATUS_COMPLETE )
        FCK.Events.AttachEvent( 'OnStatusChange', this.RefreshModeState ) ;
    else
        this.RefreshModeState() ;

    this.IsLoaded = true ;
    this.IsEnabled = true ;

    FCKTools.RunFunction( this.OnLoad ) ;
}

FCKToolbarSet.prototype.Enable = function()
{
    if ( this.IsEnabled )
        return ;

    this.IsEnabled = true ;

    var aItems = this.Items ;
    for ( var i = 0 ; i < aItems.length ; i++ )
        aItems[i].RefreshState() ;
}

FCKToolbarSet.prototype.Disable = function()
{
    if ( !this.IsEnabled )
        return ;

    this.IsEnabled = false ;

    var aItems = this.Items ;
    for ( var i = 0 ; i < aItems.length ; i++ )
        aItems[i].Disable() ;
}

FCKToolbarSet.prototype.RefreshModeState = function( editorInstance )
{
    if ( FCK.Status != FCK_STATUS_COMPLETE )
        return ;

    var oToolbarSet = editorInstance ? editorInstance.ToolbarSet : this ;
    var aItems = oToolbarSet.ItemsWysiwygOnly ;

    if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
    {
        // Enable all buttons that are available on WYSIWYG mode only.
        for ( var i = 0 ; i < aItems.length ; i++ )
            aItems[i].Enable() ;

        // Refresh the buttons state.
        oToolbarSet.RefreshItemsState( editorInstance ) ;
    }
    else
    {
        // Refresh the buttons state.
        oToolbarSet.RefreshItemsState( editorInstance ) ;

        // Disable all buttons that are available on WYSIWYG mode only.
        for ( var j = 0 ; j < aItems.length ; j++ )
            aItems[j].Disable() ;
    }
}

FCKToolbarSet.prototype.RefreshItemsState = function( editorInstance )
{

    var aItems = ( editorInstance ? editorInstance.ToolbarSet : this ).ItemsContextSensitive ;

    for ( var i = 0 ; i < aItems.length ; i++ )
        aItems[i].RefreshState() ;
}
